/*****************************************************************
 M3D Engine v0.1

 file: myd_renderer.h
 Created: 11/05/09 Re-created: 09/07/09
*****************************************************************/

#ifndef MYD_RENDERER_H
#define MYD_RENDERER_H

#include <d3dx9.h>
#include "system/myd_system.h"
#include "graphicsstructs.h"
#include "myd_vertexbuffer.h"
#include "myd_indexbuffer.h"

#pragma comment(lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

namespace myd
{
	class Texture;
	class Indexbuffer;
	class Material;

	class Renderer
	{
		//primitives
		public:
			enum PrimitiveType{
				TRIANGLE_LIST = D3DPT_TRIANGLELIST,
				TRIANGLE_STRIP = D3DPT_TRIANGLESTRIP
			};
						
			//constructer & deconstructer
			Renderer(HWND hWnd);
			~Renderer(void);

			//initialize render
			bool init();

		//scene handling
		private:
			void render_frame(void);
			void cleanD3D(void);
			void clear(void);
			void beginScene(void);
			void endScene(void);
			void present(void);
			
		//draws
		public:
			void CreateVB();
			void bind(Vertexbuffer<TextureVertex, TEXTURE_VERTEX> &VBO); 
			void bind(Indexbuffer &IBO);
			void bind(Material& mat);
			void bind(Texture& tex);

			void draw();

			/*void bind(Texture& tm_texture);
			void bind(Material& tm_material);*/

			/*void draw(const ColorVertex* vertexCollection, PrimitiveType prim,
											unsigned int uiVertexCount);

			void draw (const TextureVertex* pakVertices, PrimitiveType ePrim, 
											unsigned int uiVertexCount);*/

			//matrix handling
			void setTransform(MatrixMode mm, D3DXMATRIX mat);
			void setMatrixMode(MatrixMode eMode);
			void loadIdentity();
			void translate(float fX, float fY, float fZ = 0.0f);
			void rotateX(float fAngle);
			void rotateY(float fAngle);
			void rotateZ(float fAngle);
			void scale(float fW, float fH, float fL, float fD = 1.0f);

			void setViewPosition(float fPosX, float fPosY);

			//texture managements
			bool loadTexture (Texture& tm_texture);
			bool bindTexture(Texture& tm_texture);
			void unbindTexture();
			bool createTexture (Texture& tm_texture);
			void setCullMode(D3DCULL mode);

			// buffers
			//bool bind(VertexBuffer<>& vb);

		protected:
			//std::map <std::string, IDirect3DTexture9*> textureMap;
			//typedef std::map<std::string, IDirect3DTexture9*>::iterator TextureIterator;

			typedef std::map<std::string, IDirect3DTexture9*> TextureMap;
			TextureMap textureMap;

			typedef std::map<unsigned int, IDirect3DVertexBuffer9*> VertexBufferMap;
			VertexBufferMap vertexMap;

			typedef std::map<unsigned int, IDirect3DIndexBuffer9*> IndexBufferMap;
			IndexBufferMap indexMap;

			const Vertexbuffer<TextureVertex, TEXTURE_VERTEX>* m_pkCurrentVB;

		private:
			//initialize DirectX
			bool initDX();

			/*/vertex buffers
			Vertexbuffer<ColorVertex, COLOR_VERTEX> colorBuffer;
			Vertexbuffer<TextureVertex, TEXTURE_VERTEX> textureBuffer;*/
			
			//DirectX stuff
		private:
			IDirect3D9* D3Dobject;
			IDirect3DDevice9* D3Ddevice;

			//Windows stuff
			HWND m_hWnd;

			//current matrix mode
			MatrixMode m_eCurrentMatMode;

			//declare game as friend to call initDX
			friend class Game;

			//void setMaterial(const Material &tm_material);//<--NEW!

			unsigned int FVF;//<--NEW!!

		public:
			inline IDirect3DDevice9* getDevice(){return this->D3Ddevice;}
	};
}//end namespace

#endif //MYD_WINDOW_H